<template>
  <div>
    <el-card v-role-button="`btn.Role.search`">
      <el-form inline class="form">
        <el-form-item label="角色名:">
          <el-input placeholder="请输入角色名" v-model="nameKeywork"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :disabled="!nameKeywork" @click="search">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <el-card class="card">
      <el-button type="primary" @click="openDialog('添加角色')" v-role-button="`btn.Role.add`">添加角色</el-button>
      <el-table v-loading="loading" border :data="dataList">
        <el-table-column prop="id" label="id" align="center"></el-table-column>
        <el-table-column prop="roleName" label="角色名称" align="center" show-overflow-tooltip></el-table-column>
        <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
        <el-table-column prop="updateTime" label="更新时间" align="center"></el-table-column>
        <el-table-column label="操作" width="350" align="center">
          <template v-slot="{row}">
            <el-button type="warning" icon="User" @click="opDrawer(row)" v-role-button="`btn.Role.assgin`">分配权限</el-button>
            <el-button type="primary" icon="Edit" @click="openDialog('修改角色', row)" v-role-button="`btn.Role.update`">编辑</el-button>
            <el-popconfirm :title="`你确定要删除角色${row.roleName}吗？`" width="260" @confirm="deleteRole(row.id)" v-role-button="`btn.Role.remove`">
              <template #reference>
                <el-button type="danger" icon="Delete">删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          background
          :page-sizes="[20, 50, 100, 200, 300, 400]"
          layout="prev, pager, next, jumper, ->, total, sizes"
          :total="total"
          @currentChange="currentChange"
          @sizeChange="sizeChange"
      ></el-pagination>
    </el-card>
    <!--    添加和修改角色弹窗-->
    <el-dialog v-model="dialogFormVisible" :title="dialogTitle" @closed="closeDialog">
      <el-form style="width: 80%" label-width="100" :model="roleForm" :rules="rules" ref="formRef">
        <el-form-item label="角色名称" prop="roleName">
          <el-input placeholder="请输入角色名称" v-model="roleForm.roleName"></el-input>
        </el-form-item>
      </el-form>
      <template v-slot:footer>
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="confirm">确定</el-button>
      </template>
    </el-dialog>
    <!--    分配权限弹窗-->
    <el-drawer v-model="drawer" @closed="closeDrawer">
      <template #header>
        <span>分配权限</span>
      </template>
      <template #default>
        <el-tree
            style="max-width: 600px"
            :data="permissionList"
            show-checkbox
            node-key="id"
            default-expand-all
            :default-checked-keys="permissionIds"
            :props="defaultProps"
            ref="treeRef"
        />
      </template>
      <template #footer>
        <div style="flex: auto;text-align: right">
          <hr>
          <el-button @click="cancelDrawer">取消</el-button>
          <el-button type="primary" @click="savePermission">确认</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import {onMounted, reactive, ref, useTemplateRef} from 'vue';
import {ElMessage, type FormInstance, type TreeInstance} from "element-plus";
import {reqAllPermission, reqAllRoleList, reqDeleteRole, reqRoleAddOrUpdate, reqSetPermission} from "@/api/acl/role";
import type {
  permissionAllResponseInter,
  permissionInter,
  roleAllInter,
  roleResponseInter
} from "@/api/acl/role/type.ts";
import type {ResponseInter} from "@/api/commonInterFace.ts";

let loading = ref<boolean>(false);
let nameKeywork = ref<string>('');
let dataList = ref<roleAllInter[]>([]);
let currentPage = ref<number>(1);
// 每页条数
let pageSize = ref<number>(20);
let total = ref<number>(0)
// 搜索
const search = () => {
  getDataList()
}
// 重置搜索
const resetSearch = () => {
  nameKeywork.value = '';
  getDataList()
}

onMounted(() => {
  getDataList()
})

// 获取数据函数
const getDataList = async () => {
  loading.value = true
  let res: roleResponseInter = await reqAllRoleList(currentPage.value, pageSize.value, nameKeywork.value)
  if (res.code === 200) {
    total.value = res.data.total
    dataList.value = res.data.records
  } else {
    ElMessage.error(res.message)
  }
  loading.value = false
}
// 当前页改变
const currentChange = (newPage: number) => {
  currentPage.value = newPage
  getDataList()
}
// 每页条数改变
const sizeChange = (newSize: number) => {
  pageSize.value = newSize
  getDataList()
}


// 弹窗
let dialogFormVisible = ref<boolean>(false)
let dialogTitle = ref<string>('添加用户')
let roleForm = reactive<roleAllInter>({
  roleName: ''
})
let formRef = useTemplateRef<FormInstance>('formRef')
let rules = {
  roleName: [
    {required: true, min: 3, message: '请输入角色名称且大于3位', trigger: 'blur'}
  ]
}

// 打开弹窗
const openDialog = (title: string, row?: any) => {
  dialogTitle.value = title
  dialogFormVisible.value = true
  if (row.id) {
    roleForm.id = row.id
    roleForm.roleName = row.roleName
  }
}
// 取消
const cancel = () => {
  dialogFormVisible.value = false
}
// 关闭弹窗
const closeDialog = () => {
  roleForm.id = 0
  roleForm.roleName = ''
  formRef.value?.clearValidate()
}
// 确定
const confirm = async () => {
  await formRef.value?.validate(async valid => {
    if (!valid) return
    let res = await reqRoleAddOrUpdate(roleForm)
    if (res.code === 200) {
      ElMessage.success('操作成功')
      dialogFormVisible.value = false
      await getDataList()
    } else {
      ElMessage.error(res.message)
    }
  })

}

// 分配权限
let drawer = ref<boolean>(false)
let permissionList = ref<permissionInter[]>([])
// 过滤出已存在的权限
let permissionIds = ref<number[]>([])
let treeRef = useTemplateRef<TreeInstance>('treeRef')

const opDrawer = async (row: roleAllInter) => {
  drawer.value = true
  Object.assign(roleForm, row)
  let res: permissionAllResponseInter = await reqAllPermission(roleForm.id as number)
  if (res.code === 200) {
    permissionList.value = res.data
    permissionIds.value = filterPermission(res.data, [])
  } else {
    ElMessage.error(res.message)
  }
}
// 保存权限
const savePermission = async () => {
  let arr = treeRef.value?.getCheckedKeys() || []
  let arr1 = treeRef.value?.getHalfCheckedKeys() || []
  let permissionIdList = arr?.concat(arr1)
  let res: ResponseInter = await reqSetPermission(roleForm.id as number, permissionIdList as number[])
  if (res.code === 200) {
    ElMessage.success('操作成功')
    drawer.value = false
    window.location.reload()
  } else {
    ElMessage.error(res.message)
  }
}

// 关闭弹窗
const closeDrawer = () => {
  permissionIds.value = []
  permissionList.value = []
}
// 取消
const cancelDrawer = () => {
  drawer.value = false
}
// 树形结构数据
const defaultProps = {
  children: 'children',
  label: 'name',
}

// 删除角色
const deleteRole = async (id: number) => {
  let res: ResponseInter = await reqDeleteRole(id)
  if (res.code === 200) {
    ElMessage.success('操作成功')
    await getDataList()
  } else {
    ElMessage.error(res.message)
  }
}

const filterPermission = (data: permissionInter[], arr: any) => {
  data.forEach(item => {
    if (item.select && item.level === 4) {
      arr.push(item.id)
    }
    if (item.children && item.children.length > 0) {
      filterPermission(item.children, arr)
    }
  })
  return arr
}
</script>

<style scoped lang="scss">
.form {
  display: flex;
  align-items: center;
  justify-content: space-between;

  .el-form-item {
    margin-bottom: 0;
  }
}

.card {
  margin: 10px 0;

  .el-table {
    margin-top: 20px;
  }

  .el-pagination {
    margin-top: 20px;
  }
}
</style>
